package com.huage.courseplatform.framework.config;



import com.huage.courseplatform.framework.utils.ApplicationContextUtil;

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.Cache;
import org.apache.logging.log4j.LogManager;
import org.slf4j.Logger;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.connection.RedisServerCommands;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;

import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * ProjectName:     hello-redis-cache
 * Package:         com.laoshiren.hello.redis.cache.mybatis.cache
 * ClassName:       RedisCache
 * Author:          laoshiren
 * Description:
 * Date:            2020/9/13 15:34
 * Version:         1.0
 */
@Slf4j
public class MybatisRedisCache implements Cache {

    /**
     * 日志
     */
    /**
     * 读写锁
     */
    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    /**
     * ID,获取缓存对象的唯一标识
     */
    private String id;
    /**
     * redisTemplate
     */
    private static RedisTemplate redisTemplate;
    public MybatisRedisCache(String id) {
        if (id == null) {
            throw new IllegalArgumentException("缓存实例需要一个id!");
        } else {
            log.info("开启Redis-Mapper缓存: id = {}", id);
            this.id = id;
        }
    }
    @Override
    public String getId() {
        return this.id;
    }
    @Override
    public int getSize() {
        try {
            if (redisTemplate == null) {
                redisTemplate = getRedisTemplate();
            }
            Long size = redisTemplate.opsForHash().size("mapper:"+this.id.toString());
            //log.info("Redis-Mapper缓存大小: id = {}, size = {}", id, size);
            return size.intValue();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }
    @Override
    public void putObject(final Object key, final Object value) {
        try {
            if (redisTemplate == null) {
                redisTemplate = getRedisTemplate();
            }
            redisTemplate.opsForHash().put("mapper:"+this.id.toString(), key.toString(), value);
            /*
            log.info("设置Redis-Mapper缓存: id = {}", id);
            log.info("设置Redis-Mapper缓存: key = {}", key);
            log.info("设置Redis-Mapper缓存: value = {}",value);*/
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Override
    public Object getObject(final Object key) {
        try {
            if (redisTemplate == null) {
                redisTemplate = getRedisTemplate();
            }
            Object hashVal = redisTemplate.opsForHash().get("mapper:"+this.id.toString(), key.toString());
            /*
            log.info("获取Redis-Mapper缓存: id = {}", id);
            log.info("获取Redis-Mapper缓存: key = {}", key);
            log.info("获取Redis-Mapper缓存: hashVal = {}",hashVal);*/
            return hashVal;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    @Override
    public Object removeObject(final Object key) {
        try {
            if (redisTemplate == null) {
                redisTemplate = getRedisTemplate();
            }
            redisTemplate.opsForHash().delete("mapper:"+this.id.toString(), key.toString());
            /*
            log.info("移除Redis-Mapper缓存: id = {}", id);
            log.info("移除Redis-Mapper缓存: key = {}",key);*/
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    @Override
    public void clear() {
        try {
            if (redisTemplate == null) {
                redisTemplate = getRedisTemplate();
            }
            redisTemplate.delete("mapper:"+this.id.toString());
            //log.info("清空Redis-Mapper缓存: id = {}", id);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Override
    public ReadWriteLock getReadWriteLock() {
        return this.readWriteLock;
    }
    @Override
    public String toString() {
        return "RedisCache {" + this.id + "}";
    }
    /**
     * 由于启动期间注入失败，只能运行期间注入
     *
     * @return
     */
    public RedisTemplate getRedisTemplate() {
        redisTemplate = (RedisTemplate<String, Object>) ApplicationContextUtil.getBean("redisTemplate");
        return redisTemplate;
    }

}
